<template>
  <div style="width: 100%;">
    <el-popover placement="bottom-start" :width="600" trigger="hover"  >
      <transition name="fade">
        <div >
          <div>选择需要显示的列</div>
          <div class="dragCol">
            <el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
            <el-checkbox v-for="(item, index) in checkboxColumn" :key="index" @change="handleCheckedBoxChange(item)" v-model="item.status">{{item.label}}</el-checkbox>
          </div>
        </div>
      </transition>
      <template #reference>
          <el-button  icon="Setting">显示列</el-button>
    
      </template>
    </el-popover>
    <el-popover placement="bottom-start" :width="600" trigger="hover"  >
      <transition name="fade">
        <div >
          <div>选择需要冻结的列</div>
          <div class="dragCol">
            <el-checkbox v-model="checkFrozenAll" @change="handleFrozenCheckAllChange">全选</el-checkbox>
            <el-checkbox v-for="(item, index) in checkFrozenboxColumn" :key="index" @change="handleFrozenCheckedBoxChange(item)" v-model="item.frozen">{{item.label}}</el-checkbox>
          </div>
        </div>
      </transition>
      <template #reference>
          <el-button  icon="Setting">冻结列</el-button>
    
      </template>
    </el-popover>
    <!-- :show-summary="showSummary"  :summary-method="getSummaries" 自定义汇总方法 -->
    <el-table id="dragTable" :data="roleList" row-key="id" width="100%" stripe     :header-cell-style="{ background: '#F7F9FA !important', color: '#333' }">
         <!-- <el-table-column :width="selectionWidth " fixed="left"  type="selection" /> -->
         <el-table-column type="index" label="序号" fixed="left" width="75">
        </el-table-column>
         <template v-for="(col,index) in tableColumn" :key="index">
        <el-table-column :width="operationWidth " fixed="right" :label="col.label" :prop="col.prop" align="center" v-if="col.label === '操作'&&col.status" >
          <template #default="scope">
          <!-- 将原有操作按钮放入插槽中 -->
          <!-- scope.row 就是当前行的数据对象,在插槽中就可以使用 row 这个属性来访问当前行的数据。 -->
          <slot name="operation" :row="scope.row"></slot>
        </template>
        </el-table-column>
          <!-- 设置每一列的宽度，根据列的宽度和列的长度计算 -->
          <!-- :width="index === 0 ? flexColumnWidth(col.prop, roleList) : '300'" -->
        <el-table-column  show-overflow-tooltip :width="setColumnWidth ? flexColumnWidth(col.prop, roleList) : ''" :label="col.label" v-if="tableColumn[index].status&&tableColumn[index].label!='操作'" :fixed="tableColumn[index].frozen?'left':false" :prop="tableColumn[index].prop"  align="center" />
      </template>
    </el-table>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Sortable from 'sortablejs';

const props = defineProps({
  roleList: Array,
  Col: Array,
  showSummary: Boolean,
  setColumnWidth:Boolean,
  // summaryMethod: Function
  // 是否显示操作列
  showOperation: {
    type: Boolean,
    default: true  
  },
  //选中列宽度
  selectionWidth:{  
    type:Number,
    default:50
  },
  
  // 操作列的宽度
  operationWidth:{  
    type:Number,
    default:250
  }
});
//由于props获取的值是只读的，因此只能定义新的变量来修改
let Col=props.Col;
let newCol = props.showOperation ? [...Col, { label: '操作', prop: 'operation', status: true }] : Col;

let checkboxColumn=ref(JSON.parse(JSON.stringify(newCol)));
let checkFrozenboxColumn=ref(JSON.parse(JSON.stringify(Col)));
let tableColumn=ref(JSON.parse(JSON.stringify(newCol)));
console.log(tableColumn.value)

let checkAll = ref(true);
let checkFrozenAll = ref(true);

function handleCheckAllChange() {
  checkboxColumn.value.forEach(item => {
      item.status = checkAll.value;
  });
  tableColumn.value.forEach(i => {
          i.status=checkAll.value;
  });
}
function handleCheckedBoxChange(item) {
  const allTrue = checkboxColumn.value.every(item => item.status === true);
  // 修改显示列表的状态
  tableColumn.value.forEach(i => {
      if(i.label==item.label){
          i.status=item.status
      }
  });
  if (allTrue) {
      checkAll.value = true
  } else {
      checkAll.value = false
  }
    
}
function handleFrozenCheckAllChange() {
  checkFrozenboxColumn.value.forEach(item => {
      item.frozen = checkFrozenAll.value;
  });
  tableColumn.value.forEach(i => {
          i.frozen=checkFrozenAll.value;
  });
}
function handleFrozenCheckedBoxChange(item) {
  const allTrue = checkFrozenboxColumn.value.every(item => item.frozen === true);
  // 修改显示列表的状态
  tableColumn.value.forEach(i => {
      if(i.label==item.label){
          i.frozen=item.frozen
      }
  });
  if (allTrue) {
      checkFrozenAll.value = true
  } else {
      checkFrozenAll.value = false
  }
    
}

  function columnDrop() {
  // const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
  const wrapperTr = document.querySelector('.el-popper .dragCol')
  let sortableInstance =  Sortable.create(wrapperTr, {
      animation: 180,
      delay: 0,
      onEnd: evt => {
          let oldItem =tableColumn.value[evt.oldIndex-1]
          tableColumn.value.splice(evt.oldIndex-1,1)
          tableColumn.value.splice(evt.newIndex-1,0,oldItem)
      }
  })
}

// 自适应表格列宽
const flexColumnWidth = (str, tableData, flag = 'max') => {
  // str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
  // flag为可选值，可不传该参数,传参时可选'max'或'equal',默认为'max'
  // flag为'max'则设置列宽适配该列中最长的内容,flag为'equal'则设置列宽适配该列中第一行内容的长度。

  str = str + ''
  let columnContent = ''
  if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
      return
  }
  if (!str || !str.length || str.length === 0 || str === undefined) {
      return
  }

  if (flag === 'equal') {
      // 获取该列中第一个不为空的数据(内容)
      for (let i = 0; i < tableData.length; i++) {
          if (tableData[i][str].length > 0) {
              // console.log('该列数据[0]:', tableData[0][str])
              columnContent = tableData[i][str]
              break
          }
      }
  } else {
      // 获取该列中最长的数据(内容)
      let index = 0
      for (let i = 0; i < tableData.length; i++) {
          // 数据为空跳出循环
          // if (tableData[i][str] === null) {
          //     return
          // }
          const now_temp = tableData[i][str] + ''
          const max_temp = tableData[index][str] + ''
          if (now_temp.length > max_temp.length) {
              index = i
          }
      }
      columnContent = tableData[index][str]
  }
  // console.log('该列数据[i]:', columnContent)
  // 以下分配的单位长度可根据实际需求进行调整
  let flexWidth = 0
  columnContent = columnContent + ''
  for (const char of columnContent) {
      if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
          // 如果是英文字符，为字符分配8个单位宽度
          flexWidth += 12
      } else if (char >= '\u4e00' && char <= '\u9fa5') {
          // 如果是中文字符，为字符分配15个单位宽度
          flexWidth += 15
      } else {
          // 其他种类字符，为字符分配15个单位宽度
          flexWidth += 12
      }
  }
  if (flexWidth < 80) {
      // 设置最小宽度
      flexWidth = 180
  }
  // if (flexWidth > 250) {
  //   // 设置最大宽度
  //   flexWidth = 250
  // }
  return flexWidth + 'px'
}
// 自定义汇总方法 
const getSummaries = (param) => {
  const { columns, data } = param
  const sums = []
  columns.forEach((column, index) => {
      if (index === 0) {
          sums[index] = '总数'
          return
      }
      // console.log(column.property);
      // 将所有元素的值转换成数字类型
      const values = data.map((item) => Number(item[column.property]))
      // console.log(values.some((val) => Number.isNaN(val)));
      // every 只要有一个是数字，就会返回true
      // 判断数组中的数据是否是数字类型 some 只要存在一个是NaN那么就返回false
      if (!values.some((value) => Number.isNaN(value))) {
          sums[index] = ` ${values.reduce((prev, curr) => {
              const value = Number(curr)
              if (!Number.isNaN(value)) {
                  return prev + curr
              } else {
                  return prev

              }
          }, 0)}`
      } else {
          sums[index] = '/'
      }
  })

  return sums
}

onMounted(() => {
  columnDrop();
});
</script>

<style scoped>

.box{
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
}
.table-popover{
 margin-left: 1504px;  

}
/* 可能需要的样式 */
</style>